package com.divemotor.ventarepuestosinternet.controller;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import org.primefaces.model.LazyDataModel;

import com.divemotor.ventarepuestosinternet.beans.adapter.ClienteAdapter;
import com.divemotor.ventarepuestosinternet.beans.adapter.UsuarioClienteAdapter;
import com.divemotor.ventarepuestosinternet.beans.form.ClienteBeanForm;
import com.divemotor.ventarepuestosinternet.beans.lazy.UsuarioClienteLazy;
import com.divemotor.ventarepuestosinternet.exception.DivemotorBusinessException;
import com.divemotor.ventarepuestosinternet.model.Cliente;
import com.divemotor.ventarepuestosinternet.model.TipoDocumento;
import com.divemotor.ventarepuestosinternet.model.Usuario;
import com.divemotor.ventarepuestosinternet.model.UsuarioCliente;
import com.divemotor.ventarepuestosinternet.service.ClienteService;
import com.divemotor.ventarepuestosinternet.service.UsuarioClienteService;
import com.divemotor.ventarepuestosinternet.util.Constantes;
import com.divemotor.ventarepuestosinternet.util.Encriptacion;
import com.divemotor.ventarepuestosinternet.util.FacesContextUtil;
import com.divemotor.ventarepuestosinternet.util.Paginacion;

@ManagedBean(name="usuarioClienteController")
@ViewScoped
public class UsuarioClienteController implements Serializable {

	private static final Logger logger = Logger.getLogger(UsuarioClienteController.class);
	
	private static final long serialVersionUID = 1L;
	
	@ManagedProperty(value = "#{clienteService}")
	private ClienteService clienteService;
	@ManagedProperty(value = "#{usuarioClienteService}")
	private UsuarioClienteService usuarioClienteService;
	
	private ClienteBeanForm clienteForm;
	private ClienteAdapter cliente;
	private List<Cliente> listaClientes;
    private TipoDocumento tipoDocumentoNuevo;
    private TipoDocumento tipoDocumentoEditar;
	private LazyDataModel<ClienteAdapter> listaClientesLazy;
	private List<TipoDocumento> listaTipoDocumentos; 
	private Usuario usuarioNuevo;
	private Usuario usuarioEditar;
	private UsuarioCliente usuarioCliente; 
	private UsuarioCliente usuarioClienteNuevo; 
	private UsuarioCliente usuarioClienteEditar;
	private UsuarioClienteAdapter usuarioClienteEliminar;
	private List<UsuarioClienteAdapter> listaUsuarioCliente;
	
	private boolean cambiarContrasenia;

	public UsuarioClienteController() {	
		logger.info("UsuarioClienteController");
		
		clienteForm 			= new ClienteBeanForm();
		cliente 				= new ClienteAdapter();
		
		usuarioEditar 			= new Usuario();
	    usuarioNuevo 			= new Usuario();
		
		listaClientes 			= new ArrayList<Cliente>(0);
		usuarioCliente 			= new UsuarioCliente();
		usuarioClienteNuevo 	= new UsuarioCliente();
		usuarioClienteEditar 	= new UsuarioCliente();
		usuarioClienteEliminar 	= new UsuarioClienteAdapter();
		listaUsuarioCliente 	= new ArrayList<UsuarioClienteAdapter>(0);
		tipoDocumentoNuevo 		= new TipoDocumento();
		listaTipoDocumentos 	= new ArrayList<TipoDocumento>(0);
		tipoDocumentoEditar 	= new TipoDocumento();
	} 
	
	@PostConstruct
	public void init() {
		logger.info("init");
		buscarClientes();
		listarTipoDocumento();
	}
	
	public void buscarClientes() {
		Paginacion paginacion = new Paginacion();
		paginacion.setCliente(clienteForm);
		listaClientesLazy = new UsuarioClienteLazy(clienteService, paginacion);
	}
	
	public void listarTipoDocumento(){
		try {
			listaTipoDocumentos  = usuarioClienteService.listarTipoDocumento();
		} catch (DivemotorBusinessException e) {			
			logger.error("EX* listarTipoDocumento DivemotorBusinessException: " + e.getMessage());
		} catch (Exception e) {
			logger.error("EX* listarTipoDocumento Exception: " + e.getMessage());
		}
	}
	
	public void limpiarFiltro(){
		clienteForm.limpiarForm();
	}
	
	public void cargarDetalleCliente(ClienteAdapter cliente){
		try {
			this.cliente = cliente;
			listaUsuarioCliente = usuarioClienteService.listarUsuariosPorCliente(cliente.getIdCliente());
		} catch (DivemotorBusinessException e) {			
			logger.error("EX* cargarDetalleCliente DivemotorBusinessException: " + e.getMessage());
		} catch (Exception e) {
			logger.error("EX* cargarDetalleCliente Exception: " + e.getMessage());
		}
	}
	
	public void limpiarFormNuevoUsuario(){
		logger.info("limpiarFormNuevoUsuario");
		usuarioClienteNuevo = new UsuarioCliente();
		tipoDocumentoNuevo  = new TipoDocumento();
		usuarioNuevo 		= new Usuario();
	}
	
	public void cargarDetalleUsuarioClienteEditar(UsuarioClienteAdapter usuarioCliente){
		logger.info("cargarDetalleUsuarioClienteEditar");
		try {
			usuarioClienteEditar 	= usuarioClienteService.obtenerPorId(usuarioCliente.getIdUsuarioCliente());
			usuarioEditar 			= usuarioClienteEditar.getUsuario();
			cambiarContrasenia 		= false;
			tipoDocumentoEditar 	= new TipoDocumento();
			tipoDocumentoEditar 	= usuarioClienteEditar.getTipoDocumento();
		} catch (DivemotorBusinessException e) {
			logger.error("EX* cargarDetalleUsuarioClienteEditar: " + e.getMessage());
		}
	}
	
	private boolean validarUsuarioCliente(UsuarioCliente usuarioCliente, Usuario usuario){
		
		boolean errorTelefono = StringUtils.isBlank(usuarioCliente.getTelefonoFijo())
								&& StringUtils.isBlank(usuarioCliente.getTelefonoRpm())
								&& StringUtils.isBlank(usuarioCliente.getTelefonoRpc())
								&& StringUtils.isBlank(usuarioCliente.getTelefonoNextel());

		boolean errorContrasenias = !usuario.getContrasenia().equals(usuario.getRepetirContrasenia());
		
		if(errorContrasenias && errorTelefono){
			RequestContext.getCurrentInstance(). addCallbackParam("ocurrioError", true);
			FacesContextUtil.error(Constantes.MSJ_USUARIO_CONTRASENIAS_TELEFONO);
			return false;
		}
		
		if(errorContrasenias){
			RequestContext.getCurrentInstance(). addCallbackParam("ocurrioError", true);
			FacesContextUtil.error(Constantes.MSJ_CONTRASENIAS_DIFERENTES);
			return false;
		}
		
		if(errorTelefono){
			RequestContext.getCurrentInstance(). addCallbackParam("ocurrioError", true);
			FacesContextUtil.error(Constantes.MSJ_USUARIO_SIN_TELEFONO);
			return false;
		}
		
		return true;
	}

	public void guardarUsuarioClienteNuevo() {
		try {
			if(validarUsuarioCliente(usuarioClienteNuevo, usuarioNuevo)){
				usuarioClienteNuevo.setIdCliente(cliente.getIdCliente());
				usuarioClienteNuevo.setUsuario(usuarioNuevo);
				usuarioClienteNuevo.setTipoDocumento(tipoDocumentoNuevo);
				usuarioClienteService.insertar(usuarioClienteNuevo);
				FacesContextUtil.info(Constantes.MSJ_USUARIO_REGISTRO_OK);
				listarUsuariosPorCliente();
			}
		} catch (DivemotorBusinessException e) {				
			logger.error("EX* guardarUsuarioClienteNuevo DivemotorBusinessException: " + e.getMessage());
			RequestContext.getCurrentInstance(). addCallbackParam("ocurrioError", true);
			FacesContextUtil.warn(e.getMessage());
		} catch (Exception e) {
			logger.error("EX* guardarUsuarioClienteNuevo Exception: " + e.getMessage());
			RequestContext.getCurrentInstance(). addCallbackParam("ocurrioError", true);
			FacesContextUtil.error(Constantes.MSJ_ERROR_SISTEMA);
		}
	}

	public void listarUsuariosPorCliente(){
		try {
			listaUsuarioCliente = usuarioClienteService.listarUsuariosPorCliente(cliente.getIdCliente());
		} catch (DivemotorBusinessException e) {
			logger.error("EX* listarUsuariosPorCliente: " + e.getMessage());
		}
	}
	
	public void actualizarUsuarioCliente(){
		try {
			if(validarUsuarioCliente(usuarioClienteEditar, usuarioEditar)){
				if(cambiarContrasenia){
					usuarioEditar.setContrasenia(Encriptacion.encriptarMD5(usuarioEditar.getContrasenia()));
				}
				usuarioClienteEditar.setIdCliente(cliente.getIdCliente());
				usuarioClienteEditar.setUsuario(usuarioEditar);
				usuarioClienteEditar.setTipoDocumento(tipoDocumentoEditar);
				usuarioClienteService.actualizar(usuarioClienteEditar);
				FacesContextUtil.info(Constantes.TITULO_MENSAJE, Constantes.MSJ_USUARIO_ACTUALIZADO_OK);
				listarUsuariosPorCliente();
			}
		} catch (DivemotorBusinessException e) {
			logger.error("EX* actualizarUsuarioCliente DivemotorBusinessException: " + e.getMessage());
			RequestContext.getCurrentInstance(). addCallbackParam("ocurrioError", true);
			FacesContextUtil.warn(e.getMessage());
		} catch (Exception e) {
			logger.error("EX* actualizarUsuarioCliente Exception: " + e.getMessage());
			RequestContext.getCurrentInstance(). addCallbackParam("ocurrioError", true);
			FacesContextUtil.error(Constantes.MSJ_ERROR_SISTEMA);
		} 
	}
	
	public void eliminarUsuarioCliente() {
		try {
			UsuarioCliente usuarioCliente = usuarioClienteService.obtenerPorId(usuarioClienteEliminar.getIdUsuarioCliente());
     		usuarioClienteService.eliminar(usuarioCliente);
     		listarUsuariosPorCliente();
			FacesContextUtil.info(Constantes.MSJ_USUARIO_ELIMINADO_OK);		
		} catch (DivemotorBusinessException e) {			
			logger.error("EX* eliminarUsuarioCliente DivemotorBusinessException: " + e.getMessage());
			FacesContextUtil.warn(e.getMessage());
		} catch (Exception e) {
			logger.error("EX* eliminarUsuarioCliente Exception: " + e.getMessage());
			FacesContextUtil.error(Constantes.MSJ_ERROR_SISTEMA);
		}
	}
		
	public List<Cliente> getListaClientes() {
		return listaClientes;
	}

	public void setListaClientes(List<Cliente> listaClientes) {
		this.listaClientes = listaClientes;
	}
	
	public UsuarioCliente getUsuarioCliente() {
		return usuarioCliente;
	}

	public void setUsuarioCliente(UsuarioCliente usuarioCliente) {
		this.usuarioCliente = usuarioCliente;
	}

	public UsuarioCliente getUsuarioClienteNuevo() {
		return usuarioClienteNuevo;
	}

	public void setUsuarioClienteNuevo(UsuarioCliente usuarioClienteNuevo) {
		this.usuarioClienteNuevo = usuarioClienteNuevo;
	}

	public UsuarioCliente getUsuarioClienteEditar() {
		return usuarioClienteEditar;
	}

	public void setUsuarioClienteEditar(UsuarioCliente usuarioClienteEditar) {
		this.usuarioClienteEditar = usuarioClienteEditar;
	}
	
	public UsuarioClienteAdapter getUsuarioClienteEliminar() {
		return usuarioClienteEliminar;
	}

	public void setUsuarioClienteEliminar(
			UsuarioClienteAdapter usuarioClienteEliminar) {
		this.usuarioClienteEliminar = usuarioClienteEliminar;
	}

	public List<UsuarioClienteAdapter> getListaUsuarioCliente() {
		return listaUsuarioCliente;
	}

	public void setListaUsuarioCliente(List<UsuarioClienteAdapter> listaUsuarioCliente) {
		this.listaUsuarioCliente = listaUsuarioCliente;
	}
	
	public void setClienteService(ClienteService clienteService) {
		this.clienteService = clienteService;
	}

	public void setUsuarioClienteService(UsuarioClienteService usuarioClienteService) {
		this.usuarioClienteService = usuarioClienteService;
	}

	public LazyDataModel<ClienteAdapter> getListaClientesLazy() {
		return listaClientesLazy;
	}

	public void setListaClientesLazy(LazyDataModel<ClienteAdapter> listaClientesLazy) {
		this.listaClientesLazy = listaClientesLazy;
	}

	public ClienteBeanForm getClienteForm() {
		return clienteForm;
	}

	public void setClienteForm(ClienteBeanForm clienteForm) {
		this.clienteForm = clienteForm;
	}

	public ClienteAdapter getCliente() {
		return cliente;
	}

	public void setCliente(ClienteAdapter cliente) {
		this.cliente = cliente;
	}

	public TipoDocumento getTipoDocumentoNuevo() {
		return tipoDocumentoNuevo;
	}

	public void setTipoDocumentoNuevo(TipoDocumento tipoDocumentoNuevo) {
		this.tipoDocumentoNuevo = tipoDocumentoNuevo;
	}

	public List<TipoDocumento> getListaTipoDocumentos() {
		return listaTipoDocumentos;
	}

	public void setListaTipoDocumentos(List<TipoDocumento> listaTipoDocumentos) {
		this.listaTipoDocumentos = listaTipoDocumentos;
	}

	public Usuario getUsuarioNuevo() {
		return usuarioNuevo;
	}

	public void setUsuarioNuevo(Usuario usuarioNuevo) {
		this.usuarioNuevo = usuarioNuevo;
	}

	public Usuario getUsuarioEditar() {
		return usuarioEditar;
	}

	public void setUsuarioEditar(Usuario usuarioEditar) {
		this.usuarioEditar = usuarioEditar;
	}

	public TipoDocumento getTipoDocumentoEditar() {
		return tipoDocumentoEditar;
	}

	public void setTipoDocumentoEditar(TipoDocumento tipoDocumentoEditar) {
		this.tipoDocumentoEditar = tipoDocumentoEditar;
	}

	public boolean isCambiarContrasenia() {
		return cambiarContrasenia;
	}

	public void setCambiarContrasenia(boolean cambiarContrasenia) {
		this.cambiarContrasenia = cambiarContrasenia;
	}
	
}
